<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .wrap {
        width: 100%;
        height: 100px;
        display: flex;
        flex-wrap: wrap;
      }
      .wrap-item {
        width: 12.5%;
        font-size: 12px;
        display: flex;
        justify-content: space-between;
        align-items: center;
      }
      .data {
        display: inline-block;
        margin-right: 20px;
        width: 40%;
        height: 20px;
        line-height: 20px;
        text-align: center;
        background-color: rgba(0, 0, 0, 0.1);
      }

      .chart {
        width: 600px;
        height: 500px;
      }

      .pid-wrap {
        display: flex;
        align-items: center;
        margin-top: 50px;
      }
      .pid-item {
        display: flex;
        align-items: center;
        font-size: 30px;
        line-height: 30px;
      }
      input {
        margin: 0 20px 0 10px;
        width: 100px;
        font-size: 15px;
        height: 25px;
        line-height: 25px;
      }
      button {
        margin-left: 20px;
        width: 60px;
        height: 30px;
      }
      .update {
        position: relative;
      }
      .tip {
        width: 60px;
        text-align: center;
        position: absolute;
        top: -150%;
        left: 50%;
        transform: translateX(-50%);
      }
    </style>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.2.0/dist/echarts.min.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  </head>
  <body>
    <div id="app">
      <!-- 最新一行数据 -->
      <div class="wrap">
        <div class="wrap-item" v-for="(item,index) in dataName">
          <span>{{item}}</span>
          <span class="data">{{curData[index]}}</span>
        </div>
      </div>

      <div style="display: flex; align-items: flex-start">
        <!-- 散点图 -->
        <div ref="scatterChart" class="chart"></div>

        <!-- PID -->
        <div class="pid-wrap">
          <div class="pid-item" v-for="(item, index) in ['p','i','d']">
            <span>{{textPID(item)}}</span>
            <input
              type="text"
              v-model.number="formData[item]"
              :placeholder="'请输入'+ item + '值'"
            />
          </div>
          <button @click="onUpdatePID" class="update">
            修改
            <span v-if="timer" :style="tipColor" class="tip">{{tip}}</span>
          </button>
          <button @click="onClean" style="margin-left: 50px">清屏</button>
        </div>
      </div>
    </div>

    <script>
      var app = new Vue({
        el: "#app",
        data: {
          origin_x: 0,
          origin_y: 0,
          offset_x: 110,
          offset_y: 90,
          timer: null, // 提示定时器
          isUpdate: true, // 是否修改成功
          dataLi: [], //[[x值,y值]]
          curData: [], // 存放最新一行数据
          formData: {
            // pid数据
            p: 0,
            i: 0,
            d: 0,
          },
          dataName: [
            "Num",
            "Encoder_Left",
            "Encoder_Right",
            "AX",
            "AY",
            "AZ",
            "GX",
            "GY",
            "GZ",
            "MX",
            "MY",
            "MZ",
            "Sensor_Left",
            "Sensor_Middle",
            "Sensor_Right",
            "Sensor",
            "Angle",
            "Servo",
            "Motor_A",
            "Motor_B",
            "Velocity_KP",
            "Velocity_KI",
          ],
        },
        computed: {
          textPID() {
            return (item) => {
              return `${item.toUpperCase()}值`;
            };
          },
          tip() {
            return this.isUpdate ? "修改成功" : "修改失败";
          },
          tipColor() {
            return this.isUpdate ? "color: green" : "color: red";
          },
        },
        methods: {
          // 更新PID
          onUpdatePID() {
            // 非数字退出
            for (let key in this.formData) {
              if (typeof this.formData[key] !== "number") {
                this.isUpdate = false;
                this.tipStart();
                return;
              }
            }

            axios
              .get("http://39.108.58.51:80/updatePID", {
                params: this.formData,
              })
              .then((res) => {
                if (res.data) {
               //   console.log(res.data);
                  this.isUpdate = true;
                  this.tipStart();
                } else {
                  this.isUpdate = false;
                  this.tipStart();
                }
              })
              .catch(() => {
                this.isUpdate = false;
                this.tipStart();
              });
          },

          // 清屏
          onClean() {
            this.origin_x = 0;
            this.origin_y = 0;
            this.curData = [];
            this.dataLi = [];
            this.scatterChart.setOption({
              series: [{ data: this.dataLi }],
            });
          },

          // 开启提示定时器
          tipStart() {
            this.timer = setTimeout(() => {
              this.timer = null;
            }, 1000);
          },
        },
        mounted() {
          // 50ms请求一次数据
          setInterval(() => {
            axios.get("http://39.108.58.51:80/GetData").then((res) => {
              
              if (res.data) {
                const rawData = res.data.split(",");
                this.curData = rawData;
            //    console.log(rawData[1])
                // 处理得到[x,y]坐标值
                const mega_x = parseInt(rawData[9]),
                  mega_y = parseInt(rawData[10]),
                  left_encoder = parseInt(rawData[1]),
                  right_encoder = parseInt(rawData[2]);

                const dist = (left_encoder + right_encoder) / 2;
                const angle =
                  Math.atan2(mega_x - this.offset_x, mega_y - this.offset_y) -
                  0.93 * Math.PI;
                const x = parseInt(this.origin_x + dist * Math.cos(angle));
                const y = parseInt(this.origin_y - dist * Math.sin(angle));
                this.origin_x = x;
                this.origin_y = y;
                this.dataLi.push([x, y]);

                // 更新散点图
                this.scatterChart.setOption({
                  series: [{ data: this.dataLi }],
                });
              }
            });
          }, 50);

          // 散点图
          this.scatterChart = echarts.init(this.$refs.scatterChart);
          const option = {
            title: {
              text: "小车轨迹散点图",
              top: "5%",
            },
            tooltip: {},
            grid: {
              top: "20%",
              bottom: "20%",
            },
            animation: false,
            xAxis: {
              name: "位移x",
              type: "value",
              // scale: true,
            },
            yAxis: {
              name: "位移y",
              type: "value",
              // scale: true,
            },
            series: [
              {
                type: "scatter",
                data: this.dataLi,
                tooltip: {
                  formatter: "{c}",
                },
                itemStyle: {
                  color: "skyblue",
                },
              },
            ],
          };
          this.scatterChart.setOption(option);
        },
      });
    </script>
  </body>
</html>
